package com.ruoyi.system.controller;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.List;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.IOaOtheraPurchaseService;
import com.ruoyi.system.service.IOaProjectInitiationService;
import com.ruoyi.system.service.IOaSupplierPayableSummaryService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.service.IOaPaySumService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 应付汇总去付款Controller
 *
 * @author ruoyi
 * @date 2025-03-18
 */
@RestController
@RequestMapping("/system/sum")

public class OaPaySumController extends BaseController {
    @Autowired
    private IOaPaySumService oaPaySumService;
    @Autowired
    private IOaSupplierPayableSummaryService oaSupplierPayableSummaryService;
    @Autowired
    private IOaOtheraPurchaseService oaOtheraPurchaseService;
    @Autowired
    private IOaProjectInitiationService oaProjectInitiationService;

    /**
     * 查询应付汇总去付款列表
     */
    @PreAuthorize("@ss.hasPermi('system:sum:list')")
    @GetMapping("/list")
    public TableDataInfo list(OaPaySum oaPaySum) {
        startPage();
        List<OaPaySum> list = oaPaySumService.selectOaPaySumList(oaPaySum);
        return getDataTable(list);
    }

    /**
     * 导出应付汇总去付款列表
     */
    @PreAuthorize("@ss.hasPermi('system:sum:export')")
    @Log(title = "应付汇总去付款", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, OaPaySum oaPaySum) {
        List<OaPaySum> list = oaPaySumService.selectOaPaySumList(oaPaySum);
        ExcelUtil<OaPaySum> util = new ExcelUtil<OaPaySum>(OaPaySum.class);
        util.exportExcel(response, list, "应付汇总去付款数据");
    }

    /**
     * 获取应付汇总去付款详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:sum:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return success(oaPaySumService.selectOaPaySumById(id));
    }

    /**
     * 新增应付汇总去付款
     */
//
//    public AjaxResult add1(@RequestBody OaPaySum oaPaySum) {
//        // 检查 oaPaySum 和 totalAmount 是否为空
//        if (oaPaySum == null || oaPaySum.getTotalAmount() == null) {
//            throw new IllegalArgumentException("OaPaySum 或 totalAmount 不能为空");
//        }
//        if (oaPaySum.getPaymentAmount().compareTo(oaPaySum.getTotalAmount()) > 0){
//            throw new RuntimeException("付款金额不能大于等于需付款金额");
//        }
//        // 判断是否超过需付款金额，超过了就改为已结清
//        OaPaySum queryPaySum = new OaPaySum();
//        queryPaySum.setInitiationId(oaPaySum.getInitiationId());
//        queryPaySum.setSupplierId(oaPaySum.getSupplierId());
//        List<OaPaySum> oaPaySums = oaPaySumService.selectOaPaySumList(queryPaySum);
//        BigDecimal totalAmount = oaPaySum.getPaymentAmount();
//
//        BigDecimal totalPaymentAmount =  BigDecimal.ZERO;
//        totalPaymentAmount=  calculateTotalPaymentAmount(oaPaySums);
//        System.out.println("======================");
//        System.out.println(totalAmount);
//        System.out.println(oaPaySum.getSupplierId());
//        System.out.println(totalPaymentAmount);
//        //如果totalPaymentAmount是0为什么加不上totalAmount
//        totalPaymentAmount.add(totalAmount);
//        System.out.println(totalPaymentAmount);
//        System.out.println("======================");
//        // 检查总付款金额是否超过需付款金额
//        if ( totalPaymentAmount.compareTo(totalAmount) > 0) {
//            OaSupplierPayableSummary querySupplierSummary = new OaSupplierPayableSummary();
//            querySupplierSummary.setInitiationId(oaPaySum.getInitiationId());
//            querySupplierSummary.setSupplierName(oaPaySum.getSupplierId());
//            List<OaSupplierPayableSummary> oaSupplierPayableSummaries = oaSupplierPayableSummaryService.selectOaSupplierPayableSummaryList(querySupplierSummary);
//            if (oaSupplierPayableSummaries.size()>=2){
//                throw new RuntimeException("供应商重复,请核实供应商");
//            }
//            if (!oaSupplierPayableSummaries.isEmpty()) {
//
//                OaSupplierPayableSummary summary = oaSupplierPayableSummaries.get(0);
//                System.out.println(summary);
//                summary.setIsAmountSettled("已结清");
//                oaSupplierPayableSummaryService.updateOaSupplierPayableSummary(summary);
//            }
//            throw new RuntimeException("付款金额不能超过需付款金额");
//        }
//        int o = oaPaySumService.insertOaPaySum(oaPaySum);
//        List<OaPaySum> oaPaySums1 = oaPaySumService.selectOaPaySumList(queryPaySum);
//        // 获取付款金额
//        StringBuilder stringBuilder = new StringBuilder();
//        for (int i = 0; i < oaPaySums1.size(); i++) {
//            OaPaySum sum = oaPaySums1.get(i);
//            stringBuilder.append(sum.getPaymentAmount().toString());
//            if (i < oaPaySums1.size() - 1) {
//                stringBuilder.append(",");
//            }
//        }
//        System.out.println("更新白表付款金额");
//        // 获取付款时间
//        StringBuilder stringBuilder1 = new StringBuilder();
//        for (int i = 0; i < oaPaySums1.size(); i++) {
//            OaPaySum sum = oaPaySums1.get(i);
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//            String formattedDate1 = sdf.format(sum.getCreatedDate());
//            stringBuilder1.append(formattedDate1);
//            if (i < oaPaySums1.size() - 1) {
//                stringBuilder1.append(",");
//            }
//        }
//        System.out.println("更新白表付款时间");
//        //aaaaaaaaaaaaaaaaaaa更新白表付款金额 和付款时间
//        OaOtheraPurchase oaOtheraPurchase = new OaOtheraPurchase();
//        oaOtheraPurchase.setInitiationId(String.valueOf(oaPaySum.getInitiationId()));
//        oaOtheraPurchase.setPurchaseTableSequence(oaPaySum.getSupplierId());
//        List<OaOtheraPurchase> oaOtheraPurchases = oaOtheraPurchaseService.selectOaOtheraPurchaseList(oaOtheraPurchase);
//        if (oaOtheraPurchases.size()>=2){
//            throw new RuntimeException("供应商重复,请核实供应商");
//        }
//        oaOtheraPurchases.get(0).setPaymentAmount(stringBuilder.toString());
//        oaOtheraPurchases.get(0).setReimbursementPaymentDate(stringBuilder1.toString());
//        oaOtheraPurchaseService.updateOaOtheraPurchase(oaOtheraPurchases.get(0));
//        System.out.println("设置实际成本和利润率");
//        //bbbbbbbbbbbbbb设置实际成本和利润率
//        // 根据 initiationId 查询采购记录列表
//        OaOtheraPurchase queryParam = new OaOtheraPurchase();
//        queryParam.setInitiationId(String.valueOf(oaPaySum.getInitiationId()));
//        List<OaOtheraPurchase> purchaseList = oaOtheraPurchaseService.selectOaOtheraPurchaseList(queryParam);
//
//        // 累加所有采购记录的付款金额
//        BigDecimal totalPaymentAmount1 = BigDecimal.ZERO;
//        for (OaOtheraPurchase purchase : purchaseList) {
//            String[] split = purchase.getPaymentAmount().split(",");
//            for (String s : split) {
//                totalPaymentAmount1 = totalPaymentAmount1.add(new BigDecimal(s));
//            }
//        }
//        // 根据 initiationId 查询项目启动信息
//        OaProjectInitiation projectInitiation = oaProjectInitiationService.selectOaProjectInitiationById(Integer.parseInt(String.valueOf(oaPaySum.getInitiationId())));
//        if (projectInitiation == null) {
//            return AjaxResult.error("未找到对应的项目启动信息，initiationId: " + oaPaySum.getInitiationId());
//        }
//        // 设置实际成本
//        projectInitiation.setActualCost(totalPaymentAmount1);
//        // 计算利润率
//        BigDecimal profitMargin = calculateProfitMargin(projectInitiation.getQuotedPrice(), totalPaymentAmount);
//        projectInitiation.setProfitMargin(profitMargin+"%");
//        oaProjectInitiationService.updateOaProjectInitiation(projectInitiation);
//        System.out.println("结束了");
//        return toAjax(o);
//    }

//    private BigDecimal calculateTotalPaymentAmount(List<OaPaySum> oaPaySums) {
//        if (oaPaySums == null || oaPaySums.isEmpty()) {
//            return BigDecimal.ZERO;
//        }
//        BigDecimal total = BigDecimal.ZERO;
//        for (OaPaySum sum : oaPaySums) {
//            BigDecimal paymentAmount = sum.getPaymentAmount();
//            if (paymentAmount != null) {
//                total = total.add(paymentAmount);
//            }
//        }
//        return total;
//    }

    /**
     * 修改应付汇总去付款
     */
    @PreAuthorize("@ss.hasPermi('system:sum:edit')")
    @Log(title = "应付汇总去付款", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody OaPaySum oaPaySum) {
        return toAjax(oaPaySumService.updateOaPaySum(oaPaySum));
    }

    /**
     * 删除应付汇总去付款
     */
    @PreAuthorize("@ss.hasPermi('system:sum:remove')")
    @Log(title = "应付汇总去付款", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(oaPaySumService.deleteOaPaySumByIds(ids));
    }



    @PreAuthorize("@ss.hasPermi('system:sum:add')")
    @Log(title = "应付汇总去付款", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody OaPaySum oaPaySum) {
        validateInput(oaPaySum);
        List<OaPaySum> oaPaySums = getOaPaySums(oaPaySum);
        BigDecimal totalPaymentAmount = calculateTotalPaymentAmount(oaPaySums);
        BigDecimal currentPaymentAmount = BigDecimal.ZERO;
        currentPaymentAmount = oaPaySum.getPaymentAmount().setScale(2, RoundingMode.HALF_UP);
        BigDecimal newTotalPaymentAmount = totalPaymentAmount.add(currentPaymentAmount);
        logPaymentInfo(currentPaymentAmount, oaPaySum.getSupplierId(), totalPaymentAmount, newTotalPaymentAmount);
        checkPaymentLimit(oaPaySum, newTotalPaymentAmount);
        int insertResult = oaPaySumService.insertOaPaySum(oaPaySum);
        List<OaPaySum> updatedOaPaySums = getOaPaySums(oaPaySum);
        updateOtheraPurchase(oaPaySum, updatedOaPaySums);
        updateProjectInitiation(oaPaySum, updatedOaPaySums);
        return toAjax(insertResult);
    }

    private void validateInput(OaPaySum oaPaySum) {
        BigDecimal currentPaymentAmount = oaPaySum.getPaymentAmount();
        currentPaymentAmount = currentPaymentAmount.setScale(2, BigDecimal.ROUND_HALF_UP);
        if (oaPaySum == null || oaPaySum.getTotalAmount() == null) {
            throw new IllegalArgumentException("OaPaySum 或 totalAmount 不能为空");
        }
        if ( oaPaySum.getAllowablePayment() == null) {
            throw new IllegalArgumentException("OaPaySum 或 AllowablePayment 不能为空");
        }
        if (currentPaymentAmount.compareTo(oaPaySum.getAllowablePayment()) > 0) {
            throw new RuntimeException("付款金额不能大于需付款金额");
        }
    }

    //找到同应付汇总的数据
    private List<OaPaySum> getOaPaySums(OaPaySum oaPaySum) {
        OaPaySum queryPaySum = new OaPaySum();
        queryPaySum.setPaybleSummaryId(oaPaySum.getPaybleSummaryId());
        return oaPaySumService.selectOaPaySumList(queryPaySum);
    }

    private void logPaymentInfo(BigDecimal currentPaymentAmount, String supplierId, BigDecimal totalPaymentAmount, BigDecimal newTotalPaymentAmount) {
        System.out.println("======================");
        System.out.println(currentPaymentAmount+"本次付款金额");
        System.out.println(supplierId+"供应商名");
        System.out.println(totalPaymentAmount+"历史付款金额");
        System.out.println(newTotalPaymentAmount+"历史付款金额家当前");
        System.out.println("======================");
    }

    private void checkPaymentLimit(OaPaySum oaPaySum, BigDecimal newTotalPaymentAmount) {
        System.out.println( oaPaySum.getAllowablePayment()+"需付款金额");
        System.out.println(newTotalPaymentAmount+"历史金额2");
        if (newTotalPaymentAmount.compareTo(oaPaySum.getAllowablePayment()) > 0) {
            throw new RuntimeException("付款金额不能超过需付款金额");
        }
    }

    private void updateOtheraPurchase(OaPaySum oaPaySum, List<OaPaySum> oaPaySums) {
        // 检查 oaPaySum 和 oaPaySums 是否为空
        if (oaPaySum == null) {
            throw new IllegalArgumentException("传入的 oaPaySum 不能为 null");
        }
        if (oaPaySums == null) {
            throw new IllegalArgumentException("传入的 oaPaySums 不能为 null");
        }
        String paymentAmounts = joinPaymentAmounts(oaPaySums);
        String paymentDates = joinPaymentDates(oaPaySums);
        // 应付汇总表 id
        Long paybleSummaryId = oaPaySum.getPaybleSummaryId();
        if (paybleSummaryId == null) {
            throw new NullPointerException("oaPaySum 中的 paybleSummaryId 为 null");
        }
        OaSupplierPayableSummary oaSupplierPayableSummary = oaSupplierPayableSummaryService.selectOaSupplierPayableSummaryById(paybleSummaryId);
        if (oaSupplierPayableSummary == null) {
            throw new NullPointerException("根据 paybleSummaryId 未找到对应的 OaSupplierPayableSummary 记录");
        }
        String otheraPurchaseId = oaSupplierPayableSummary.getOtheraPurchaseId();
        if (otheraPurchaseId == null) {
            throw new NullPointerException("OaSupplierPayableSummary 中的 otheraPurchaseId 为 null");
        }
        if (otheraPurchaseId.contains(",")) {

        } else {
         long   parsedId = Long.parseLong(otheraPurchaseId.trim());
            OaOtheraPurchase oaOtheraPurchase1 = oaOtheraPurchaseService.selectOaOtheraPurchaseById(parsedId);

            if (oaOtheraPurchase1 == null) {
                throw new NullPointerException("根据 otheraPurchaseId 未找到对应的 OaOtheraPurchase 记录");
            }
            oaOtheraPurchase1.setPaymentAmount(paymentAmounts);
            oaOtheraPurchase1.setReimbursementPaymentDate(paymentDates);
            oaOtheraPurchaseService.updateOaOtheraPurchase(oaOtheraPurchase1);
        }

    }

    private String joinPaymentAmounts(List<OaPaySum> oaPaySums) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < oaPaySums.size(); i++) {
            OaPaySum sum = oaPaySums.get(i);
            stringBuilder.append(sum.getPaymentAmount().toString());
            if (i < oaPaySums.size() - 1) {
                stringBuilder.append(",");
            }
        }
        return stringBuilder.toString();
    }

    private String joinPaymentDates(List<OaPaySum> oaPaySums) {
        StringBuilder stringBuilder = new StringBuilder();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < oaPaySums.size(); i++) {
            OaPaySum sum = oaPaySums.get(i);
            String formattedDate1 = sdf.format(sum.getCreatedDate());
            stringBuilder.append(formattedDate1);
            if (i < oaPaySums.size() - 1) {
                stringBuilder.append(",");
            }
        }
        return stringBuilder.toString();
    }

    private void updateProjectInitiation(OaPaySum oaPaySum, List<OaPaySum> oaPaySums) {
        BigDecimal totalPaymentAmount = calculateTotalPaymentAmount(oaPaySums);
        Long initiationId = oaPaySum.getInitiationId();
        OaProjectInitiation projectInitiation = oaProjectInitiationService.selectOaProjectInitiationById(initiationId.intValue());
        if (projectInitiation == null) {
            throw new RuntimeException("未找到对应的项目启动信息，initiationId: " + oaPaySum.getInitiationId());
        }
        projectInitiation.setActualCost(totalPaymentAmount);
        BigDecimal profitMargin =projectInitiation.getQuotedPrice().subtract(projectInitiation.getTotalActualAmount());
        BigDecimal profitMargin1 = profitMargin.divide(projectInitiation.getQuotedPrice() ,2, RoundingMode.HALF_UP);
        projectInitiation.setProfitMargin(profitMargin1 + "%");
        oaProjectInitiationService.updateOaProjectInitiation(projectInitiation);
    }

    private BigDecimal calculateTotalPaymentAmount(List<OaPaySum> oaPaySums) {
        if (oaPaySums == null || oaPaySums.isEmpty()) {
            return BigDecimal.ZERO;
        }
        BigDecimal total = BigDecimal.ZERO;
        for (OaPaySum sum : oaPaySums) {
            BigDecimal paymentAmount = sum.getPaymentAmount();
            if (paymentAmount != null) {
                total = total.add(paymentAmount);
            }
        }
        return total;
    }
}
